#include <SimpleDef.h>
#include <Utility/CLib.h>
#include <Utility/intrinsic.h>
#include <IntExcept/IntExcept.h>
#include <IntExcept/Debug.h>
#include <IntExcept/Debug.h>
#include <IO/VideoTextMode.h>
#include <Memory/Segmentation.h>
#include <Memory/Paging.h>
#include <ProcessThread/ProcessThread.h>
#include <IO/Keyboard.h>

/*
@brief 中断处理函数派发
@param `lpIntExceptContext` 触发中断时保存的上下文
*/
void DispatchIntExceptHandler(LPIntExceptContext lpIntExceptContext)
{
    if (lpIntExceptContext->dwVector == 0xE) /* 缺页中断 */
    {
        if (READ_CR2_32() == 0)
        {
            printk("cs:eip = %x:%x\r\n", lpIntExceptContext->dwCS, lpIntExceptContext->dwEIP);
            printk("ss:esp = %x:%x\r\n", lpIntExceptContext->dwSS, lpIntExceptContext->dwESP);
        }
        KERNEL_ASSERT(READ_CR2_32() != 0, "Attempt to dereference NULL.\r\n");
        KERNEL_ASSERT(HandlePageFault(0), "Fails to handle #PF. #PF error code = %d. CR2 = 0x%x.\r\n", lpIntExceptContext->dwErrorCode, READ_CR2_32());
    }
    else if (lpIntExceptContext->dwVector == 0x20)
    {
        ScheduleThread(lpIntExceptContext);
    }
    else if (lpIntExceptContext->dwVector == 0x21)
    {
        // printk("Keyboard Interupt.\r\n");
        AppendCharToKeyboardInputBuffer(g_lpKeyboardInputBuffer);
        VideoTextModePutChar(RetrieveCharFromKeyboardInputBuffer(g_lpKeyboardInputBuffer)); 
    }
}